package com.kizuki.thread;

import org.junit.Test;

import java.util.concurrent.*;

public class TestCallable {

    /**
     * 线程池配合future和callable最常用
     * @param args
     * @throws ExecutionException
     * @throws InterruptedException
     */
    public static void main(String[] args) throws ExecutionException, InterruptedException {

        ExecutorService ser = Executors.newFixedThreadPool(10); // 创建一个可重用固定线程数的线程池

        // execute 适应于runnable接口
        ser.execute(() -> System.out.println("runnable execute"));

        // submit 适应于callable接口
        Future submit1 = ser.submit(new TestCall("Testsubmit"));

        Object o = submit1.get();// Callable 执行有返回值
        System.out.println(o);

        ser.shutdown(); // 关闭服务
    }

    @Test
    public void testCallable(){
        /**
         * 思路
         * new Thread(runnable).start();
         * new Thread(new FutureTask()).start(); // futureTask是runnable
         * new Thread(new FutureTask(Callable)).start(); // Callable初始化futureTask
         */

        TestCall ca = new TestCall("ca");

        // 借助FutureTask类，获取返回结果
        FutureTask futureTask = new FutureTask<>(ca);

        /**
         * 虽然有两个线程, 但是结果有缓存所以只输出
         * ca_TestCallable
         * main: java.lang.Object@6f2b958e
         */
        new Thread(futureTask).start();
        new Thread(futureTask).start();

        try {
            Object o = futureTask.get(); // 会阻塞 不知道什么时候返回
            System.out.println(Thread.currentThread().getName()+": "+o);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }


    }

}

class TestCall implements Callable<Object>{

    private String name;

    public TestCall(String name) {
        this.name = name;
    }

    public TestCall() {
    }

    @Override
    public Object call() throws Exception {
        System.out.println(this.name + "_TestCallable");
        return new Object();
    }


}
